package com.ztsoft.user.service.dynamic.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.ztsoft.user.common.exception.CustomException;
import com.ztsoft.user.mapper.dynamic.DynamicTableMapper;
import com.ztsoft.user.pojo.entity.dynamic.ColumnDescription;
import com.ztsoft.user.pojo.entity.dynamic.DynamicConfig;
import com.ztsoft.user.pojo.entity.dynamic.DynamicTable;
import com.ztsoft.user.pojo.enums.ResultCode;
import com.ztsoft.user.pojo.vo.PageData;
import com.ztsoft.user.pojo.vo.PageInfo;
import com.ztsoft.user.pojo.vo.ResultData;
import com.ztsoft.user.pojo.vo.TableInfo;
import com.ztsoft.user.pojo.vo.dynamic.*;
import com.ztsoft.user.service.dynamic.ColumnDescriptionService;
import com.ztsoft.user.service.dynamic.DynamicConfigService;
import com.ztsoft.user.service.dynamic.DynamicFormService;
import com.ztsoft.user.service.dynamic.DynamicTableService;
import com.ztsoft.user.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DynamicTableServiceImpl extends ServiceImpl<DynamicTableMapper, DynamicTable> implements DynamicTableService {
    @Autowired
    private DynamicFormService dynamicFormService;
    @Autowired
    private DynamicConfigService dynamicConfigService;
    @Autowired
    private ColumnDescriptionService columnDescriptionService;

    /**
     * 获取自定义表格
     */
    @Override
    public ResultData queryTableByTableCode(String tableCode) {
        DynamicTableVo dynamicTableVo = baseMapper.listMapByTableCode(tableCode);
        return newResultData(dynamicTableVo);
    }

    /**
     * 返回所有表格编码
     *
     * @return
     */
    @Override
    public List<String> getAllTableCode() {
        return baseMapper.getAllTableCode();
    }

    /**
     * 返回分页及数据信息
     *
     * @param tableCode
     * @param pageInfo
     * @param searchItemVo
     * @return
     */
    @Override
    public PageData queryDataByTableCode(String tableCode, PageInfo pageInfo, SearchItemVo searchItemVo) {
        // 由表格编码查找表
        DynamicTableVo dynamicTableVo = baseMapper.listMapByTableCode(tableCode);
        // 由表格编码查找表字段
        List<ColumnDescriptionVo> list = columnDescriptionService.getColumnDescriptionVos(dynamicTableVo.getTableCode());

        DynamicSqlVo dynamicSqlVo = generateTableDynamicSqlVo(dynamicTableVo, list, searchItemVo, pageInfo);
        List<Map<String, Object>> dataList = new ArrayList<>();
        if (!dynamicSqlVo.getSelectField().trim().isEmpty()) {
            dataList = baseMapper.getDataList(dynamicSqlVo);
            int count = baseMapper.getDataListCount(dynamicSqlVo);
            pageInfo.setTotal(count);
        }
        return new PageData(dataList, pageInfo);
    }

    //高级搜索相关
    @Override
    public List<AdvancedSearchVo> querySearchByTableCode(String tableCode) {
        DynamicTableVo dynamicTableVo = baseMapper.listMapByTableCode(tableCode);
        List<ColumnDescriptionVo> list = columnDescriptionService.getColumnDescriptionVos(dynamicTableVo.getTableCode());
        List<AdvancedSearchVo> advancedSearchVoList = new ArrayList<>();
        list.forEach(column -> {
            if (Boolean.TRUE.equals(column.getSearchable() && column.getField() != null) && !"".equals(column.getField())) {
                AdvancedSearchVo advanced = new AdvancedSearchVo();
                advanced.setFieldCode(column.getSelectField());
                advanced.setFieldName(column.getTitle());
                advanced.setFieldType("input");
                advancedSearchVoList.add(advanced);
            }
        });
        return advancedSearchVoList;
    }

    @Override
    public void saveDynamicTable(DynamicTable dynamicTable) {
        List<String> sqlTableNameList = dynamicTable.getSqlTableNameList();
        StringBuilder sqlTableName = new StringBuilder();
        sqlTableNameList.forEach(str -> sqlTableName.append(str).append("#"));
        dynamicTable.setSqlTableName(sqlTableName.toString());
        this.save(dynamicTable);
    }

    //设置where条件和对应的值
    private void whereSqlAndParam(SearchItemVo searchItemVo, List<String> whereList, Map<String, Object> whereParam) {
        Map<String, Object> paramMap = searchItemVo.getParamMap();
        //设置普通的查询语句
        if (!paramMap.isEmpty()) {
            paramMap.forEach((key, value) -> {
                if (value != null && !"".equals(value)) {
                    List<ColumnDescription> field1 = columnDescriptionService.list(new QueryWrapper<ColumnDescription>().eq("field", key));
                    for (ColumnDescription columnDescription : field1) {
                        String field = columnDescription.getSelectField();
                        whereList.add(" and " + field + " like concat('%', #{whereParam." + key + "} ,'%') ");
                    }

                    whereParam.put(key, value);
                }
            });
        }
        //设置高级搜索
        List<Map<String, Object>> multiConditionList = searchItemVo.getMultiConditionList();
        if (multiConditionList != null && !multiConditionList.isEmpty()) {
            String condition = searchItemVo.getCondition();
            for (Map<String, Object> map : multiConditionList) {
                String value = String.valueOf(map.get("content"));
                String key = String.valueOf(map.get("fieldsName"));
                String operator = String.valueOf(map.get("operator"));
                if (key != null && !key.trim().isEmpty()) {
                    String paramKey = key.replace(".", "_");
                    String field = columnDescriptionService.getOne(new QueryWrapper<ColumnDescription>().eq("field", paramKey)).getSelectField();
                    whereList.add(condition + " " + field + " " + operator + " #{whereParam." + paramKey + "}  ");
                    whereParam.put(paramKey, value);
                }
            }
        }
    }

    //生成需要查询的字段
    private String generateSelectField(List<ColumnDescriptionVo> list) {
        StringBuilder selectFieldSql = new StringBuilder(" ");
        for (ColumnDescriptionVo columnDescription : list) {
            String selectField = columnDescription.getSelectField();
            String field = columnDescription.getField();
            if (selectField != null && !selectField.equals("")) {
                selectFieldSql.append(selectField);
                if (!"".equals(field)) {
                    selectFieldSql.append(" as '").append(field).append("' ");
                }
                selectFieldSql.append(" ,");
            }
        }
        return selectFieldSql.substring(0, selectFieldSql.length() - 1);
    }

    //from后面的sql
    private String fromSql(DynamicTableVo dynamicTableVo) {
        return (dynamicTableVo.getFromSql() == null || dynamicTableVo.getFromSql().trim().isEmpty()) ? dynamicTableVo.getSqlTableName() : dynamicTableVo.getFromSql();
    }

    //初始化返回参数
    private ResultData newResultData(DynamicTableVo dynamicTableVo) {
        //设置基础属性
        TableInfo tableInfo = new TableInfo(dynamicTableVo);
        List<ColumnDescriptionVo> list = columnDescriptionService.getColumnDescriptionVos(dynamicTableVo.getTableCode());
        //设置表格相关配置
        generateTableConfig(tableInfo, dynamicTableVo.getTableCode());
        tableInfo.setColumns(list);
        ResultData resultData = new ResultData(tableInfo);
        //获取搜索项和搜索项验证
        dynamicFormService.generateForm(resultData, dynamicTableVo.getTableCode());
        return resultData;
    }

    //设置分页
    private String pageSql(PageInfo pageInfo) {
        StringBuilder page = new StringBuilder();
        long size = pageInfo.getPageSize();
        long mount = pageInfo.getCurrentPage();
        if (size > 0) {
            if (mount != 0) {
                mount = (mount - 1) * size;
            }
            page.append(" limit ").append(mount).append(" , ").append(size);
        }
        return page.toString();
    }

    //生成表格配置
    private void generateTableConfig(TableInfo tableInfo, String tableCode) {
        List<DynamicConfig> configList = dynamicConfigService.list(new QueryWrapper<DynamicConfig>().eq("table_code", tableCode));
        for (DynamicConfig dynamicConfig : configList) {
            try {
                if (Boolean.TRUE.equals(dynamicConfig.getStatus())) {
                    String contents = dynamicConfig.getContents();
                    Gson gson = new Gson();
                    Map<String, Object> map = new HashMap<>();
                    map = gson.fromJson(contents, map.getClass());
                    tableInfo.put(dynamicConfig.getConfigType(), map);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new CustomException(ResultCode.FAILED.getMsg(), ResultCode.FAILED.getCode());
            }
        }
    }

    //生成查询要的相关信息
    private DynamicSqlVo generateTableDynamicSqlVo(DynamicTableVo dynamicTableVo, List<ColumnDescriptionVo> list, SearchItemVo searchItemVo, PageInfo pageInfo) {
        String selectField = generateSelectField(list);
        String fromSql = fromSql(dynamicTableVo);
        List<String> whereList = new ArrayList<>();
        Map<String, Object> whereParam = new HashMap<>();
        whereSqlAndParam(searchItemVo, whereList, whereParam);
        String pageSql = pageSql(pageInfo);
        return new DynamicSqlVo(selectField, fromSql, whereList, whereParam, pageSql);
    }


    ///////////////////////////////////////////////////改造//////////////////////////////////////////////////////////////


    /**
     * 带条件分页查询
     *
     * @param dynamicTable 条件实体
     * @param currentPage  当前页
     * @param pageSize     当前页面大小
     * @return 结果值
     */
    @Override
    public Result<Object> queryDataByPage(DynamicTable dynamicTable, Integer currentPage, Integer pageSize) {
        Map<String, Object> resultMap = new HashMap<>();

        QueryWrapper<DynamicTable> queryWrapper = new QueryWrapper<>(dynamicTable);
        IPage<DynamicTable> page = this.page(new Page<>(currentPage, pageSize), queryWrapper);

        resultMap.put("count", page.getTotal());
        resultMap.put("data", page.getRecords());
        return Result.success(resultMap);
    }

}